#!/usr/local/bin/python3
# -*- coding: utf-8 -*-

"""
@File    : trans_scatter.py
@Author  : Link
@Time    : 2022/6/4 11:00
@Mark    : 
"""

import math

import numpy as np
import pandas as pd

from PySide2 import QtWidgets, QtCore

from chart_core.chart_pyqtgraph.utils import CustomViewBox, PlotWidget, InfiniteLine, \
    ScatterPlotItem, mkPen, Mixin, graph_range_signal, colormap


class TransScatterChart(QtCore.QObject, Mixin):
    """
    散点图
    初始化就需要有两个scatter_item, 一个放front_df, 另一个放chart_df
    不应该精简数据, 直接show出全部好了
    """
    key = None
    li = None

    bins_num = 5000  # 在这里表示, 一次show多少颗

    # 选取
    select_start = 0
    select_stop = 0

    # x
    front_data_min = 0
    front_data_max = 0

    list_bins = None
    lines = None  # 线
    unit = ''  # 默认单位
    front_scatter_dict = None

    def __init__(self):
        super(TransScatterChart, self).__init__()
        self.vb = CustomViewBox()
        self.pw = PlotWidget(viewBox=self.vb, enableMenu=False)
        self.pw.hideButtons()
        self.pw.addLegend(colCount=2)
        self.bottom_axis = self.pw.getAxis("bottom")
        self.bottom_axis.setHeight(60)
        self.left_axis = self.pw.getAxis("left")
        self.left_axis.setWidth(60)
        # self.pw.setMouseEnabled(x=False)
        self.vb.select_signal.connect(self.select_range)
        self.front_scatter_dict = dict()
        color = colormap.get('./colors/CET-C6.csv')
        self.c = color.getLookupTable(alpha=True)
        self.rota = 0b11001

    def init_movable_line(self):
        v_line = InfiniteLine(angle=90, movable=False, label='x={value:0.0f}', labelOpts={'color': (0, 0, 0)})
        h_line = InfiniteLine(angle=0, movable=False, label='y={value:0.5f}', labelOpts={'color': (0, 0, 0)})
        self.vb.addItem(v_line, ignoreBounds=True)
        self.vb.addItem(h_line, ignoreBounds=True)

        def mouseMoved(evt):
            if self.vb.sceneBoundingRect().contains(evt):
                mouse_point = self.vb.mapSceneToView(evt)
                v_line.setPos(mouse_point.x())
                h_line.setPos(mouse_point.y())

        self.vb.scene().sigMouseMoved.connect(mouseMoved)

    def set_data(self, key: str, data_min=None, data_max=None):
        if self.li is None:
            raise Exception("first set li")
        self.key = key
        self.set_title(key)
        self.front_data_min, self.front_data_max = data_min, data_max
        if data_min is None:
            self.front_data_min = self.li.front_df["PART_ID"].min()
        if data_max is None:
            self.front_data_max = self.li.front_df["PART_ID"].max()
        self.bottom_axis.setRange(self.front_data_min, self.front_data_max)

    def select_range(self, ax: QtCore.QRectF):
        pass

    @graph_range_signal
    def set_front_df_chart(self):
        """
        scatter chart需要的主要参数为 x,y,pen,brush,size
        scatter chart需要保证数据都要被展示到. x使用part_id
        :return:
        """
        if self.key not in self.li.front_df:
            return
        # temp_df = self.li.front_df[
        #     (self.li.front_df["PART_ID"] > self.front_data_min) & (self.li.front_df["PART_ID"] < self.front_data_max)]
        # if len(temp_df) == 0:
        #     return
        scatter_size = 5
        if len(self.li.front_df) > 2E3:
            scatter_size = 3
        self.list_bins = int(abs(self.front_data_min - self.front_data_max) // self.bins_num)
        for key, each in self.front_scatter_dict.items():
            each.clear()
        group_item = self.li.front_df.groupby(["GROUP", "DA_GROUP"])
        color_square_nm = math.ceil(pow(len(group_item), 0.5))
        color_split_nm = 512 / 2 ** color_square_nm
        color_list = self.c[::int(color_split_nm)]
        for index, (key, e_df) in enumerate(group_item):
            idx = int(index % color_split_nm)
            x = e_df["PART_ID"][::self.list_bins + 1]  # type:pd.Series
            y = e_df[self.key][::self.list_bins + 1]  # type:pd.Series
            temp_key = f"front{key[0]}|{key[1]}"
            if temp_key not in self.front_scatter_dict:
                plot = ScatterPlotItem(symbol='o', size=scatter_size, pen=None, name=key, brush=tuple(color_list[idx]))
                plot.addPoints(x.to_numpy(), y.to_numpy())
                self.front_scatter_dict[temp_key] = plot
                self.pw.addItem(plot)
            else:
                plot = self.front_scatter_dict[temp_key]
                plot.setData(x.to_numpy(), y.to_numpy(), clear=True)

            # self.pw.plot(x.to_numpy(), y.to_numpy(), pen=None, symbol='t', symbolSize=5, symbolPen=None, name=key,
            #              symbolBrush=(100, 100, 255, 50))

    @graph_range_signal
    def set_chart_df_chart(self):
        pass

    def full_change_chart(self):
        self.set_front_df_chart()
        self.set_chart_df_chart()
